package com.tencent.qf.web.wrap;

import lombok.extern.slf4j.Slf4j;
import org.apache.commons.io.input.BoundedInputStream;

import java.io.BufferedReader;
import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import javax.servlet.ReadListener;
import javax.servlet.ServletInputStream;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletRequestWrapper;

/**
 * Copyright (C) 2022 Limited, a Tencent company. All rights reserved.
 *
 * @author p_htaozhou@tencent.com
 * @create: 2022/9/23 17:54
 */
@Slf4j
public class MultiReadHttpServletRequestWrapper extends HttpServletRequestWrapper {

    // We include a max byte size to protect against malicious requests,
    //since this all has to be read into memory
    public static final Integer MAX_BYTE_SIZE = 1_048_576; // 1 MB

    public StringBuilder body;

    public MultiReadHttpServletRequestWrapper(HttpServletRequest request) throws IOException {
        super(request);
        body = new StringBuilder();
        try (InputStream bounded = new BoundedInputStream(request.getInputStream(), MAX_BYTE_SIZE);
             BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(bounded))) {
            String line;
            while ((line = bufferedReader.readLine()) != null) {
                body.append(line);
            }
        } catch (Exception e) {
            log.error(e.getMessage());
        }

    }


    @Override
    public ServletInputStream getInputStream() {
        final ByteArrayInputStream byteArrayInputStream = new ByteArrayInputStream(body.toString().getBytes());
        return new ServletInputStream() {
            @Override
            public int read() {
                return byteArrayInputStream.read();
            }

            @Override
            public boolean isFinished() {
                return byteArrayInputStream.available() == 0;//byteArrayInputStream.available() == 0
            }

            @Override
            public boolean isReady() {
                return true;
            }

            @Override
            public void setReadListener(ReadListener listener) {

            }
        };
    }

    @Override
    public BufferedReader getReader() {
        return new BufferedReader(new InputStreamReader(this.getInputStream()));
    }
}

